class Interface {
  constructor(name, methods=[], properties=[]) {    
    this.name = name;
    this.methods = [];
    this.properties = [];
  
    for (let i = 0, len = methods.length; i < len; i++) {
      if (typeof methods[i] !== 'string') {
        throw new Error("Konstruktor interfejsu oczekuje na wejściu nazw metod w postaci łańcuchów.");
      }
      this.methods.push(methods[i]);
    }
    
    for (let i = 0, len = properties.length; i < len; i++) {
      if (typeof properties[i] !== 'string') {
        throw new Error("Konstruktor interfejsu oczekuje na wejściu nazw własności w postaci łańcuchów.");
      }
      this.properties.push(properties[i]);
    }
  }
  
  isImplementedBy(obj) {
    var methodsLen = this.methods.length;
    var propertiesLen = this.properties.length;
    var currentMember;
    
    if (obj) {
      // sprawdzenie metod
      for (let i = 0; i < methodsLen; i++) {
        currentMember = this.methods[i];
        if (!obj[currentMember] || typeof obj[currentMember] !== "function") {
          throw new Error("Obiekt nie implementuje interfejsu " + this.name + ". Nie znaleziono metody " + currentMember + ".");
        } 
      }
      
      //check properties
      for (let i = 0; i < propertiesLen; i++) {
        currentMember = this.properties[i];
        if (!obj[currentMember] || typeof obj[currentMember] === "function") {
          throw new Error("Obiekt nie implementuje interfejsu " + this.name + ". Nie znaleziono własności " + currentMember + ".");
        } 
      }
    } else {
      throw new Error("Brak obiektu do sprawdzenia!");
    }
  }
}